﻿using Awsc.DataAcquisitionSys.Core.DataAcquisition;
using Awsc.DataAcquisitionSys.Core.Model;
using Awsc.DataAcquisitionSys.Core.Models.ServiceModels;
using Awsc.DataAcquisitionSys.Core.Service.Alarm.Interfaces;


namespace Awsc.DataAcquisitionSys.Core.Service.Alarm.Implement
{
    public abstract class AlarmRule : IAlarmRule, IDisposable
    {
        private readonly object _syncLock = new();
        private CancellationTokenSource _cts = new();
        private Task _executionTask = Task.CompletedTask;
        private bool _disposed;

        public int Id { get; set; }
        public string Name { get; set; } = string.Empty;
        public string Description { get; set; }
        public RuleStatus Status { get; set; } = RuleStatus.Inactive;
        public AlarmLevel AlarmLevel { get; set; }
        public bool IsBuildInRule { get; set; }
        public List<IAlarmMethod> AlarmMethods { get; set; } = new();
        public AlarmRuleType RuleType { get; set; }
        public string Condition { get; set; }

        public abstract List<string> GetAllFieldNames();
        protected abstract bool Evaluate(Dictionary<string, object> parameters);

        public async Task Activate()
        {
            lock (_syncLock)
            {
                if (Status == RuleStatus.Active || _disposed) return;

                Status = RuleStatus.Active;
                _cts.Dispose();
                _cts = new CancellationTokenSource();

                // 确保之前的任务已完成
                if (_executionTask?.IsCompleted == false)
                    _executionTask.ContinueWith(_ => StartExecution()).ConfigureAwait(false);
                else
                    StartExecution();
            }
        }



        public async Task Deactivate()
        {
            lock (_syncLock)
            {
                if (Status == RuleStatus.Inactive || _disposed) return;

                Status = RuleStatus.Inactive;
                _cts.Cancel();
            }
        }

        public void AddAlarmMethod(IAlarmMethod method)
        {
            if (method == null) return;

            lock (_syncLock)
            {
                if (_disposed) return;
                if (AlarmMethods.Any(m => m == method)) return;

                AlarmMethods.Add(method);
            }
        }

        public void RemoveAlarmMethod(IAlarmMethod method)
        {
            if (method == null) return;

            lock (_syncLock)
            {
                if (_disposed) return;

                if (AlarmMethods
                    .Any(m => m == method))
                {
                    AlarmMethods.Remove(method);
                }

            }
        }
        private void StartExecution()
        {
            _executionTask = Task.Run(() => ExecuteInternalAsync(_cts.Token), _cts.Token);
        }


        private async Task ExecuteInternalAsync(CancellationToken cancellationToken)
        {
            const int normalPollingInterval = 2000;
            const int emptyMethodsInterval = 2000;
            const int missingDataInterval = 1000;


            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    // 快速检查状态变化
                    if (Status == RuleStatus.Inactive)
                    {
                        await Task.Delay(normalPollingInterval, cancellationToken);
                        continue;
                    }

                    // 检查告警方法是否可用
                    if (!AlarmMethods.Any())
                    {
                        await Task.Delay(emptyMethodsInterval, cancellationToken);
                        continue;
                    }

                    // 获取传感器数据
                    var fieldNames = GetAllFieldNames();
                    var sensors = GlobalDeviceManager.Instance.GetSensors(fieldNames);

                    // 检查数据完整性
                    if (sensors.Any(s =>! s.IsValid))
                    {
                        await Task.Delay(missingDataInterval, cancellationToken);
                        continue;
                    }

                    // 评估告警条件
                    var parameters = sensors.ToDictionary(s => s.Name, s => s.CurrentValue);
                    bool shouldTriggerAlarm = Evaluate(parameters);

                    if (shouldTriggerAlarm)
                    {
                        TriggerAlarmActions(parameters);
                    }


                }
                catch (OperationCanceledException)
                {

                }
                catch (Exception ex)
                {
                    // 记录异常，但保持规则运行
                    //Logger.LogError(ex, $"Alarm rule '{Name}' execution failed");
                    Console.WriteLine(ex.Message);
                }
                // 等待下一次轮询
                await Task.Delay(normalPollingInterval, cancellationToken);
            }
        }

        

        private void TriggerAlarmActions(Dictionary<string, object> sensorDatas)
        {
            var alarmInfo = AlarmInformation.Create(Name, AlarmLevel, sensorDatas);
            var methodsSnapshot = AlarmMethods.ToArray(); // 创建快照避免并发修改

            // 并行触发所有告警方法（不等待完成）
            Parallel.ForEach(methodsSnapshot, method =>
            {
                try
                {
                    method.ExecuteAsync(alarmInfo).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    //Logger.LogError(ex, $"Alarm method {method.GetType().Name} failed for rule '{Name}'");
                }
            });
        }

        public void Dispose()
        {
            lock (_syncLock)
            {
                if (_disposed) return;

                _disposed = true;
                Status = RuleStatus.Inactive;

                _cts.Cancel();
                _cts.Dispose();

                GC.SuppressFinalize(this);
            }
        }

        ~AlarmRule() => Dispose();
    }
}
